<?php
// -------------------------------------------------------------------------------------------------------------------
class ccdsImageCache
{
    private $config;

    function __construct( )
    {
        $config=ccdsConfig::getInstance();
        ;
        $this->config=$config;

        $this->engine=$config->get( 'RESIZE_ENGINE' );
    }

    static function &getInstance( )
    {
        static $obj;

        if ( !$obj )
        {
            $obj=new ccdsImageCache();
        }
        return $obj;
    }

    function image_info( $img_src )
    {
        $engine=$this->config->get( 'RESIZE_ENGINE' );

        switch ( $engine )
            {
            case 'IMAGICK_PECL':
                $img_attrb=array();
                $handle=imagick_readimage( $img_src );

                if ( imagick_iserror( $handle ) )
                {
                    $reason=imagick_failedreason( $handle );
                    $description=imagick_faileddescription( $handle );
                    print "handle failed!<BR>\nReason: $reason<BR>\nDescription: $description<BR>\n";
                }
                else
                {
                    $img_attrb['width']=imagick_getwidth( $handle );
                    $img_attrb['height']=imagick_getheight( $handle );
                }
                break;

            case 'IMAGICK_PECL2':

                $image=new Imagick( $img_src );
                $img_attrb=$image->getImageGeometry();

                $image->destroy();
                unset( $image );

                break;

            case 'IMAGICK_SHELL':
                ob_start();
                $out=system( "convert " . $img_src . " info:-" );
                ob_get_clean();
                list( $name, $type, $size )=split( " ", $out );
                list( $x, $y )=split( "x", $size );

                $img_attrb['width']=$x;
                $img_attrb['height']=$y;
                break;
            }

        return $img_attrb;
    }


// -------------------------------------------------------------------------------------------------------------------

    function img_cache_resize( $img_src, $img_width, $img_height, $img_stretch=0, $img_quality=80 )
    {

        list( $img_org, $img_end )=preg_split( "/\./", $img_src );

        if ( $img_end != 'jpg' && $img_end != 'jpeg' && $img_end != 'gif' && $img_end != 'png' )
        {
            $img_end='jpg';
        }

        $img_destfile=
            "ccds_cache/img/" . MD5( $img_src ) . "." . $img_width . "x" . $img_height . "x" . $img_stretch . "."
            . $img_end;
        $img_destination=$this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' ) . $img_destfile;
        $create_new=false;

        if ( file_exists( $img_destination ) )
        {
            $dest_stat=stat( $img_destination );
            $source_stat=stat( $img_src );

            if ( $dest_stat['mtime'] < $source_stat['mtime'] )
            {
                $create_new=true;
                unlink( $img_destination );
            }
            else {
            //$size = $this->image_info($img_destination);
            //$img_width = $size['img_width'];
            //$img_height = $size['img_height'];
            }
        }
        else
        {
            $create_new=true;
        }

        if ( $create_new )
        {
            switch ( $this->engine )
                {
                case 'IMAGICK_PECL':
                    $handle=imagick_readimage( $img_src );

                    if ( imagick_iserror( $handle ) )
                    {
                        $reason=imagick_failedreason( $handle );
                        $description=imagick_faileddescription( $handle );
                        print "handle failed!<BR>\nReason: $reason<BR>\nDescription: $description<BR>\n";
                    }
                    $img_attrb['width']=imagick_getwidth( $handle );
                    $img_attrb['height']=imagick_getheight( $handle );

                    if ( $img_stretch == 0 )
                    {
                        if ( ( $img_attrb['width'] <= $img_width ) AND ( $img_attrb['height'] <= $img_height ) )
                        {
                            $img_width=$img_attrb['width'];
                            $img_height=$img_attrb['height'];
                        }
                    }

                    imagick_resize( $handle, $img_width, $img_height, IMAGICK_FILTER_HERMITE, .8 );
                    imagick_setcompressionquality( $handle, $img_quality );

                    if ( !imagick_writeimage( $handle, $img_destination ) )
                    {
                        $reason=imagick_failedreason( $handle );
                        $description=imagick_faileddescription( $handle );

                        print "imagick_writeimage() failed<BR>\nReason: $reason<BR>\nDescription: $description<BR>\n";
                    }
                    break;

                case 'IMAGICK_PECL2':
                    $image=new Imagick( $img_src );
                    $image->thumbnailImage( $img_width, $img_height, 1 );
                    $image->writeImage( $img_destination );
                    $img_attrb=$image->getImageGeometry();
                    $image->destroy();

                    $img_width=$img_attrb['width'];
                    $img_height=$img_attrb['height'];
                    break;

                case 'IMAGICK_SHELL':

                    $out=
                        system( "convert '" . $img_src . "' -strip -geometry " . $img_width . "x" . $img_height . " "
                        . $img_destination . " ",
                            $retval );
                    $size=$this->image_info( $img_destination );
                    $img_width=$size['width'];
                    $img_height=$size['height'];

                    break;
                }
        }
        else
        {
            $size=$this->image_info( $img_destination );
            $img_width=$size['width'];
            $img_height=$size['height'];
        }
        return array
            (
            "src" => $this->config->get( 'WEB_ROOT' ) . $img_destfile,
            "width" => $img_width,
            "height" => $img_height
            );
    }

// -------------------------------------------------------------------------------------------------------------------
    function img_cache_show( $params, &$smarty=false )
    {
        $return="";

        if ( !isset( $params['src'] ) )
            $smarty->trigger_error( 'src needed' );

        isset( $params['alt'] ) ? $img_alt=$params['alt'] : $img_alt="";
        isset( $params['width'] ) ? $img_width=$params['width'] : $img_width=$img_attrb['width'];
        isset( $params['height'] ) ? $img_height=$params['height'] : $img_height=$img_attrb['height'];
        isset( $params['stretch'] ) ? $stretch=$params['stretch'] : $stretch=0;
        isset( $params['quality'] ) ? $quality=$params['quality'] : $quality=90;
        isset( $params['border'] ) ? $border=$params['border'] : $border=0;
        isset( $params['title'] ) ? $title=$params['title'] : $title="";
        isset( $params['align'] ) ? $align=" align=\"" . $params['align'] . "\" " : $align="";

        isset( $params['id'] ) ? $img_id=$params['id'] : $img_id="rez_image_" . rand();
        isset( $params['style'] ) ? $style="style=\"" . $params['style'] . "\"" : $style="";

        if ( file_exists( $this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' ) . $params['src'] ) )
        {
            $img_src=
                $this->img_cache_resize( $this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' )
                    . $params['src'],
                    $img_width, $img_height, $stretch, $quality );
            $return=
                "<img id=\"" . $img_id . "\" border=\"" . $border . "\" " . $align . " title=\"" . $title . "\" src=\""
                . $img_src['src'] . "\"  alt=\"" . $img_alt . "\" width=\"" . $img_src['width'] . "\" height=\""
                . $img_src['height'] . "\" " . $style . " />";
        }
        else
        {
            $smarty->trigger_error( 'Image cannot be found in: ' . $this->config->get( 'DOC_ROOT' )
                . $this->config->get( 'WEB_ROOT' ) . $params['src'] );
        }

        return $return;
    }
// -------------------------------------------------------------------------------------------------------------------

    function img_cache_return_array( $params )
    {
        if ( !isset( $params['src'] ) )
            trigger_error( 'src needed' );

        $return=array();

        isset( $params['alt'] ) ? $img_alt=$params['alt'] : $img_alt="";
        isset( $params['width'] ) ? $img_width=$params['width'] : $img_width=$img_attrb['width'];
        isset( $params['height'] ) ? $img_height=$params['height'] : $img_height=$img_attrb['height'];
        isset( $params['stretch'] ) ? $stretch=$params['stretch'] : $stretch=0;
        isset( $params['quality'] ) ? $quality=$params['quality'] : $quality=90;
        isset( $params['border'] ) ? $border=$params['border'] : $border=0;
        isset( $params['title'] ) ? $title=$params['title'] : $title="";
        isset( $params['align'] ) ? $align=$params['align'] : $align="";

        isset( $params['id'] ) ? $img_id=$params['id'] : $img_id="resize_img_" . rand();
        isset( $params['style'] ) ? $style="style=\"" . $params['style'] . "\"" : $style="";

        if ( file_exists( $this->config->get( 'DOC_ROOT' ) . $params['src'] ) )
        {
            $img_src=
                $this->img_cache_resize( $this->config->get( 'DOC_ROOT' ) . $params['src'], $img_width, $img_height,
                    $stretch, $quality );
            $return["size"]=$img_size;
            $return["src"]=$img_src['src'];

            $return["width"]=$img_src['width'];
            $return["height"]=$img_src['height'];
        }
        else {

        //$smarty->trigger_error('Image cannot be found in: '.$this->config->get('DOC_ROOT').$params['src']);

        }
        return $return;
    }

// -------------------------------------------------------------------------------------------------------------------
    function img_cache_return( $params, &$smarty )
    {

        $return=$this->img_cache_return_array( $params );

        $smarty->assign( "img_" . $params['id'], $return );
    }

// -------------------------------------------------------------------------------------------------------------------
    function return_img_name( $params, &$smarty )
    {

        $img_src=$params['src'];
        $img_width=$params['width'];
        $img_height=$params['height'];

        list( $img_org, $img_end )=preg_split( "/\./", $img_src );

        if ( $img_end != 'jpg' && $img_end != 'jpeg' && $img_end != 'gif' && $img_end != 'png' )
        {
            $img_end='jpg';
        }

        $img_destfile=MD5( $img_src ) . "." . $img_width . "x" . $img_height . "." . $img_end;
        $img_destination="ccds_cache/img/" . $img_destfile;
        return $img_destination;
    }
// -------------------------------------------------------------------------------------------------------------------

    function crop( $img_src, $width, $height, $offsX, $offsY )
    {

        list( $img_org, $img_end )=preg_split( "/\./", $img_src );

        if ( $img_end != 'jpg' && $img_end != 'jpeg' && $img_end != 'gif' && $img_end != 'png' )
        {
            $img_end='jpg';
        }

        $img_destfile="ccds_cache/tmp/" . MD5( $img_src ) . '.' . $img_end;
        $img_destination=$this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' ) . $img_destfile;
        $create_new=false;

        switch ( $this->engine )
            {
            case 'IMAGICK_PECL': break;

            case 'IMAGICK_PECL2':
                $image=new Imagick( $img_src );
                $imagick->rotateImage( new ImagickPixel(), $direction );
                $imagick->writeImage( $img_destination );
                break;

            case 'IMAGICK_SHELL':
                $out=
                    system( "convert '" . $img_src . "' -crop " . $width . "x" . $height . "+" . $offsX . "+" . $offsY
                        . " -strip " . $img_destination . " ",
                        $retval );
                $size=$this->image_info( $img_destination );
                $img_width=$size['img_width'];
                $img_height=$size['img_height'];
                break;
            }

        return $img_destfile;
    }

    function rotate( $img_src, $direction )
    {

        list( $img_org, $img_end )=preg_split( "/\./", $img_src );

        if ( $img_end != 'jpg' && $img_end != 'jpeg' && $img_end != 'gif' && $img_end != 'png' )
        {
            $img_end='jpg';
        }

        $img_destfile="ccds_cache/tmp/" . MD5( $img_src ) . '.' . $img_end;
        $img_destination=$this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' ) . $img_destfile;
        $create_new=false;

        switch ( $this->engine )
            {
            case 'IMAGICK_PECL': break;

            case 'IMAGICK_PECL2':
                $image=new Imagick( $img_src );
                $imagick->rotateImage( new ImagickPixel(), $direction );
                $imagick->writeImage( $img_destination );
                break;

            case 'IMAGICK_SHELL':
                $out=
                    system( "convert '" . $img_src . "' -quality 100 -rotate " . $direction . " -strip "
                    . $img_destination . " ",
                        $retval );
                $size=$this->image_info( $img_destination );
                $img_width=$size['img_width'];
                $img_height=$size['img_height'];
                break;
            }

        return $img_destfile;
    }
}
